/**
 * @author Jonnie Spratley
 * @classDescription - Full jQuery wrapper for Twitter API. This plugin requires
 * TwitterService.php for anything to work, files must be in same location. Or
 * specified in the options of the plugin.
 * @version - 0.9
 * @projectDescription - http://code.google.com/p/jquery-jtwitter/
 * @option - defaultTimeline: 'public' - String - The default timeline to recieve. public | friends | user
 * @option - autoFetch: true,
 * @option - showActions: false,
 * @option - tweetarea: null - the id of the textarea for updating status, works well with replies
 * @option - user: null - Object - A user object holding propertys username and/or password.
 * @option - 		username: null - String - The twitter username
 * @option - 		password: null - String - The twitter user password
 * @option - search: null - Object - The next and prev link ids for paging search results.
 * @option -		next: null,
 * @option -		prev: null,
 * @option - resultLocations: - null - Object - A object containing all of the result locations.
 * @option - debug: null,
 * @option - success: null,
 * @option - error: null,
 * @option - currentUser: null,
 * @option - rateStatus: null,
 * @option - deleteTweet: null,
 * @option - getFollowing: null,
 * @option - getFollowers: null,
 * @option - getFriendsFollowers: null,
 * @option - getFriendsTimeline: null,
 * @option - getPublicTimeline: null,
 * @option - getUserTimeline: null,
 * @option - getReplies: null,
 * @option - showTweet: null,
 * @option - postTweet: null,
 * @option - getMessages: null,
 * @option - deleteMessage: null,
 * @option - createMessage: null,
 * @option - getSentMessages: null,
 * @option - getFavorites: null,
 * @option - createFavorite: null,
 * @option - deleteFavorite: null,
 * @option - followMember: null,
 * @option - unfollowMember: null,
 * @option - confirmFollow: null,
 * @option - blockMember: null,
 * @option - unblockMember: null,
 * @option - getAllFollowers: null,
 * @option - getAllFriends: null,
 * @option - getRateLimit: null,
 * @option - endSession: null,
 * @option - verifyCredentials: null,
 * @option - updateDevice: null,
 * @option - updateLocation: null,
 * @option - updateProfile: null,
 * @option - updateProfileImage: null,
 * @option - updateBackgroundImage: null,
 * @option - updateProfileColors: null,
 * @option - searchKeywords: null,
 * @option - searchTrends: null
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
(function($){
   
    var thisWrap = '';
	var inCall = false;
	var defaultSettings = {
		defaultTimeline: 'public',
		autoFetch: true,
		autoTime: 1,
		showActions: false,
		tweetarea: null,
		tweetareaCount: null,
		loader: function(bool){
		    return bool;
		},
		user: {
			username: null,
			password: null
		},
		search: {
			next: null,
			prev: null,
		},
		resultLocations: {
			debug: null,
			success: null,
			error: null,
			currentUser: null,
			rateStatus: null,
			deleteTweet: null,
			getFollowing: null,
			getFollowers: null,
			getFriendsFollowers: null,
			getFriendsTimeline: null,
			getPublicTimeline: null,
			getUserTimeline: null,
			getReplies: null,
			showTweet: null,
			postTweet: null,
			getMessages: null,
			deleteMessage: null,
			createMessage: null,
			getSentMessages: null,
			getFavorites: null,
			createFavorite: null,
			deleteFavorite: null,
			followMember: null,
			unfollowMember: null,
			confirmFollow: null,
			blockMember: null,
			unblockMember: null,
			getAllFollowers: null,
			getAllFriends: null,
			getRateLimit: null,
			endSession: null,
			verifyCredentials: null,
			updateDevice: null,
			updateLocation: null,
			updateProfile: null,
			updateProfileImage: null,
			updateBackgroundImage: null,
			updateProfileColors: null,
			searchKeywords: null,
			searchTrends: null
		}
	};

	var jtwitterUserObject = {
		created_at: new Date(),
		description: '',
		favourites_count: 0,
		followers_count: 0,
		following: 0,
		id: 0,
		location: '',
		name: '',
		notifications: true,
		profile_background_color: '000000',
		profile_background_image_url: '',
		profile_background_tile: true,
		profile_image_url: '',
		profile_link_color: '000000',
		profile_sidebar_fill_color: '000000',
		profile_sidebar_border_color: '000000',
		'protected': false,
		screen_name: '',
		statuses_count: 0,
		time_zone: '',
		url: '',
		utc_offset: 0,
		verified: false
	};
	
	var jtwitterMessageObject = {
		id: 0,
		text: '',
		created_at: new Date(),
		recipient_id: 0,
		recipient_screen_name: '',
		recipient: jtwitterUserObject,
		sender_id: 0,
		sender_screen_name: '',
		sender: jtwitterUserObject
	};
	
	var jtwitterTweetObject = {
		id: 0,
		text: '',
		created_at: new Date(),
		source: '',
		truncated: false,
		favorited: false,
		in_reply_to_screen_name: null,
		in_reply_to_status_id: null,
		in_reply_to_user_id: null,
		user: jtwitterTweetObject
	};
	
	var jtwitterRateObject = {
		reset_time_in_seconds: 0,
		reset_time: new Date(),
		remaining_hits: 0,
		hourly_limit: 0
	};
	
	var jtwitterTrendObject = {
		as_of: new Date(),
		trends: {
			name: '',
			url: ''
		}
	};
	
	var jtwitterSearchObject = {
		completed_in: 0,
		max_id: 0,
		next_page: '',
		page: 0,
		query: '',
		refresh_url: '',
		results: {
			created_at: new Date(),
			from_user: '',
			from_user_id: 0,
			id: 0,
			iso_language_code: '',
			profile_image_url: '',
			source: '',
			text: '',
			to_user_id: 0
		}
	};
	
	$.fn.jtwitter = function(url, options){

	thisWrap = $(this);
	
	var defaultOptions = $.extend(true, {}, defaultSettings, options);
	
	$.jtwitter = {
		jtwitterMethods: ["deleteTweet", "getFollowing", "getFollowers", "getFriendsFollowers", "getFriendsTimeline", "getPublicTimeline", "getUserTimeline", "getReplies", "showTweet", "postTweet", "showProfile", "getMessages", "deleteMessage", "createMessage", "getSentMessages", "followMember", "unfollowMember", "confirmFollow", "getFavorites", "createFavorite", "deleteFavorite", "blockMember", "unBlockMember", "getAllFriends", "getAllFollowers", "getRateLimit", "endSession", "verifyCredentials", "updateDevice", "updateLocation", "updateProfile", "updateBackgroundImage", "updateProfileColors", "updateProfileImage", "notification_turnOn", "notification_turnOff", "search_keywords", "search_trends", "help_test"],
		
		/**
		 * I make a get call to the proxy which then calls on the twitter api.
		 * @param {Object} method - the method to invoke
		 * @param {Object} params - the parameter object to send with the call
		 * @param {Object} callback - the callback to execute once result is recieved
		 */
		_get: function(method, params, callback){
			$.extend(params, {
				m: method
			});
			
			//@TODO: Check this 
			//if ( method != 'verifyCredentials' || method != 'getPublicTimeline' || method != 'searchKeywords' || method != 'searchTrends' ){
			
			if (defaultOptions.user.username) {
				$.extend(params, {
					u: defaultOptions.user.username
				});
			}
			
			if (defaultOptions.user.password) {
				$.extend(params, {
					p: defaultOptions.user.password
				});
			}
			
			//}
			
			//Set loading to true
			defaultOptions.loader(true);
			
			$.get(url, params, function(result){
				defaultOptions.loader(false);
				
				var resultArray = eval('(' + result + ')');
				if (callback) {
					callback(resultArray);
				}
				//return resultArray;
			});
		},
		
		/**
		 * I post data to the proxy which then posts to twitter.com
		 *
		 * @param {Object} method - the method to invoke
		 * @param {Object} params - the parameter object to send with the call
		 * @param {Object} callback - the callback to execute once result is recieved
		 */
		_post: function(method, params, callback){
			$.extend(params, {
				m: method,
				u: defaultOptions.user.username,
				p: defaultOptions.user.password
			});
			
			//Set the loader
			defaultOptions.loader(true);
			
			$.post(url, params, function(result){
				defaultOptions.loader(false);
				
				var resultArray = eval('(' + result + ')');
				if (callback) {
					callback(resultArray);
				}
			});
		},
		
		
		/**
		 * I am the methods object, I hold all of the methods that are available on the proxy.
		 * I then call upon the _get function passing all required parameters, and then handle
		 * the result by passing the result and the method called to the build function. Which
		 * then populates the specified jquery object with the formatted and build data.
		 */
		getPublicTimeline: function(callback){
			$.jtwitter._get('getPublicTimeline', {}, function(data){
				(defaultOptions.resultLocations.getPublicTimeline) ? $(defaultOptions.resultLocations.getPublicTimeline).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
			});
		},
		
		getFollowers: function( page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getFollowers', {
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getFollowers) ? $(defaultOptions.resultLocations.getFollowers).html($.jtwitter.builders.build('follower', data)) : (callback(data));
				});
			}
		},
		
		getFollowing: function(count, page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getFollowing', {
					count: count,
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getFollowing) ? $(defaultOptions.resultLocations.getFollowing).html($.jtwitter.builders.build('follower', data)) : (callback(data));
				});
			}
		},
		
		getFriendsFollowers: function(callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getFriendsFollowers', {}, function(data){
					(defaultOptions.resultLocations.getFriendsFollowers) ? $(defaultOptions.resultLocations.getFriendsFollowers).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}
		},
		
		getFriendsTimeline: function(count, page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getFriendsTimeline', {
					count: count,
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getFriendsTimeline) ? $(defaultOptions.resultLocations.getFriendsTimeline).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}	
		},
		
		getUserTimeline: function(user, count, page, callback){
			$.jtwitter._get('getUserTimeline', {
				user: user,
				count: count,
				page: page
			}, function(data){
				(defaultOptions.resultLocations.getUserTimeline) ? $(defaultOptions.resultLocations.getUserTimeline).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
			});
			
		},
		
		getReplies: function(count, page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getReplies', {
					count: count,
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getReplies) ? $(defaultOptions.resultLocations.getReplies).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}
		},
		
		showTweet: function(id, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('showTweet', {
					id: id
				}, function(data){
				
					(callback(data));
				});
			}
		},
		
		postTweet: function(text, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('postTweet', {
					status: text
				}, function(data){
				    $(defaultOptions.tweetarea).val('');
					(defaultOptions.resultLocations.getFriendsTimeline) ? $(defaultOptions.resultLocations.getFriendsTimeline).prepend($.jtwitter.builders.build('singletweet', data)) : (callback(data));
				});
			}
		},
		
		getMessages: function(count, page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getMessages', {
					count: count,
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getMessages) ? $(defaultOptions.resultLocations.getMessages).html($.jtwitter.builders.build('message', data)) : (callback(data));
				});
			}
		},
		
		getSentMessages: function(count, page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getSentMessages', {
					count: count,
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getPublicTimeline) ? $(defaultOptions.resultLocations.getPublicTimeline).html($.jtwitter.builders.build(1, data)) : (callback(data));
				});
			}
		},
		
		createMessage: function(userid, text, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('createMessage', {
					id: userid,
					text: text
				}, function(data){
					(defaultOptions.resultLocations.createMessage) ? $(defaultOptions.resultLocations.createMessage).html($.jtwitter.builders.build('message', data)) : (callback(data));
				});
			}
		},
		
		deleteMessage: function(msgid, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('deleteMessage', {
					id: msgid
				}, function(data){
					(defaultOptions.resultLocations.deleteMessage) ? $(defaultOptions.resultLocations.deleteMessage).html($.jtwitter.builders.build('message', data)) : (callback(data));
				});
			}
		},
		
		getFavorites: function( page, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getFavorites', {
					page: page
				}, function(data){
					(defaultOptions.resultLocations.getFavorites) ? $(defaultOptions.resultLocations.getFavorites).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}
		},
		
		createFavorite: function(msgid, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('createFavorite', {
					id: msgid
				}, function(data){
					(defaultOptions.resultLocations.createFavorite) ? $(defaultOptions.resultLocations.createFavorite).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}
		},
		
		deleteFavorite: function(msgid, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('deleteFavorite', {
					id: msgid
				}, function(data){
					(defaultOptions.resultLocations.deleteFavorite) ? $(defaultOptions.resultLocations.deleteFavorite).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}
		},
		
		deleteTweet: function(id, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('deleteTweet', {
					id: id
				}, function(data){
					(defaultOptions.resultLocations.deleteTweet) ? $(defaultOptions.resultLocations.deleteTweet).html($.jtwitter.builders.build('tweet', data)) : (callback(data));
				});
			}
		},
		
		followMember: function(userid, follow, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('followMember', {
					id: userid,
					follow: follow
				}, function(data){
					(defaultOptions.resultLocations.followMember) ? $(defaultOptions.resultLocations.followMember).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		unfollowMember: function(userid, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('unfollowMember', {
					id: userid
				}, function(data){
					(defaultOptions.resultLocations.unfollowMember) ? $(defaultOptions.resultLocations.unfollowMember).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		confirmFollow: function(usera, userb, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('confirmFollow', {
					a: usera,
					b: userb
				}, function(data){
					(defaultOptions.resultLocations.confirmFollow) ? $(defaultOptions.resultLocations.confirmFollow).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		blockMember: function(userid, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('blockMember', {
					id: userid
				}, function(data){
					(defaultOptions.resultLocations.blockMember) ? $(defaultOptions.resultLocations.blockMember).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		unblockMember: function(userid, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('unblockMember', {
					id: userid
				}, function(data){
					(defaultOptions.resultLocations.unblockMember) ? $(defaultOptions.resultLocations.unblockMember).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		getAllFollowers: function(callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getAllFollowers', {}, function(data){
					(defaultOptions.resultLocations.getAllFollowers) ? $(defaultOptions.resultLocations.getAllFollowers).html($.jtwitter.builders.build('countfriends', data)) : (callback(data));
				});
			}
		},
		
		getAllFriends: function(callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getAllFriends', {}, function(data){
					(defaultOptions.resultLocations.getAllFriends) ? $(defaultOptions.resultLocations.getAllFriends).html($.jtwitter.builders.build('countfriends', data)) : (callback(data));
				});
			}
		},
		
		getRateLimit: function(callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._get('getRateLimit', {}, function(data){
					(defaultOptions.resultLocations.getRateLimit) ? $(defaultOptions.resultLocations.getRateLimit).html($.jtwitter.builders.build('rate', data)) : (callback(data));
				});
			}
		},
		
		endSession: function(callback){
			$.jtwitter._post('endSession', {}, function(data){
				(defaultOptions.resultLocations.endSession) ? $(defaultOptions.resultLocations.endSession).html($.jtwitter.builders.build('user', data)) : (callback(data));
			});
		},
		
		verifyCredentials: function(user, pass, callback){
			$.extend(defaultOptions.user, {
				username: user,
				password: pass
			});
			$.jtwitter._get('verifyCredentials', {
				u: user,
				p: pass
			}, function(data){
				(defaultOptions.resultLocations.verifyCredentials) ? $(defaultOptions.resultLocations.verifyCredentials).html($.jtwitter.builders.build('user', data)) : (callback(data));
			});
		},
		
		updateDevice: function(device, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('updateDevice', {
					device: device
				}, function(data){
					(defaultOptions.resultLocations.updateDevice) ? $(defaultOptions.resultLocations.updateDevice).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		updateLocation: function(location, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('updateLocation', {
					location: location
				}, function(data){
					(defaultOptions.resultLocations.updateLocation) ? $(defaultOptions.resultLocations.updateLocation).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		updateProfile: function(name, email, url, location, desc, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('updateProfile', {
					n: name,
					e: email,
					url: url,
					l: location,
					d: desc
				}, function(data){
					(defaultOptions.resultLocations.updateProfile) ? $(defaultOptions.resultLocations.updateProfile).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		updateProfileImage: function(img, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('updateProfileImage', {
					image: img
				}, function(data){
					(defaultOptions.resultLocations.updateProfileImage) ? $(defaultOptions.resultLocations.updateProfileImage).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		updateBackgroundImage: function(img, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('updateBackgroundImage', {
					image: img
				}, function(data){
					(defaultOptions.resultLocations.updateBackgroundImage) ? $(defaultOptions.resultLocations.updateBackgroundImage).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		updateProfileColors: function(bg, text, link, sidebg, sideborder, callback){
			if ($.jtwitter.utils.checkUser()) {
				$.jtwitter._post('updateProfileColors', {
					bg: bg,
					t: text,
					sbg: sidebg,
					sb: sideborder
				}, function(data){
					(defaultOptions.resultLocations.updateProfileColors) ? $(defaultOptions.resultLocations.updateProfileColors).html($.jtwitter.builders.build('user', data)) : (callback(data));
				});
			}
		},
		
		searchKeywords: function(q, page, since, sinceid, maxid, callback){
			$.jtwitter._get('searchKeywords', {
				q: q,
				page: page,
				since: since,
				sinceid: sinceid,
				maxid: maxid
			
			}, function(data){
				(defaultOptions.resultLocations.searchKeywords) ? $(defaultOptions.resultLocations.searchKeywords).html($.jtwitter.builders.build('search', data)) : (callback(data));
			});
		},
		
		searchTrends: function(callback){
			$.jtwitter._get('searchTrends', {}, function(data){
				(defaultOptions.resultLocations.searchTrends) ? $(defaultOptions.resultLocations.searchTrends).html($.jtwitter.builders.build('trends', data)) : (callback(data));
			});
		},
		
		trimUrl: function(url, callback){
			$.jtwitter._get('trimUrl', {
				longurl: url
			}, function(data){
				( callback ) ? callback(data) : alert(data);
			});
		},
				
		
		/**
		 * I hold all of the functions that build the html from the result of a service call
		 */
		builders: {
			/**
			 * I evaluate and prep each build depending on what method was invoked
			 * @param {Object} mode - what method that was called
			 * @param {Object} data - the result object from that method
			 */
			build: function(mode, data){
				var html = '';
				
				switch (mode) {
					case 'tweet'://Timelines, Replies, Favorites,
						$.each(data, function(i, obj){
							$.extend(jtwitterTweetObject, obj);
							html += $.jtwitter.builders.buildTweets(i, jtwitterTweetObject);
						});
					break;
					case 'singletweet'://Single Status Update, Favorite, Message
						$.extend(jtwitterTweetObject, data);		
						html += $.jtwitter.builders.buildTweets(jtwitterTweetObject);		
					break;			
					case 'message'://Messages, Sent Messages
						$.each(data, function(i, obj){
							$.extend(jtwitterMessageObject, obj);
							html += $.jtwitter.builders.buildMessages(i, jtwitterMessageObject);
						});
					break;			
					case 'follower'://Followers Image List
						$.each(data, function(i, obj){
							$.extend(jtwitterUserObject, obj);
							html += $.jtwitter.builders.buildImages(i, jtwitterUserObject);
						});
					break;		
					case 'user'://User Update Status, Profile changes, etc user 						 
						$.extend(jtwitterUserObject, data);
						html += $.jtwitter.builders.buildUser(null, jtwitterUserObject);
					break;		
					case 'search'://User Update Status, Profile changes, etc user 
						$.extend(jtwitterSearchObject, data);
						$.each(jtwitterSearchObject.results, function(i, obj){
							html += $.jtwitter.builders.buildSearch(i, obj);
						});
					break;		
					case 'trends'://User Update Status, Profile changes, etc user 
						$.extend(jtwitterTrendObject, data);
						$.each(jtwitterTrendObject.trends, function(i, obj){
							html += $.jtwitter.builders.buildTrends(i, obj);
						});
					break;		
					case 'rate': //Rate Status 
						$.extend(jtwitterRateObject, data);
						html += $.jtwitter.builders.buildRateStatus(jtwitterRateObject);
					break;
				}
				return html;
			},
			
			buildTweets: function(i, tweetObj){
			    tweetObj.text = $.jtwitter.utils.filterUrl( tweetObj.text );
			    tweetObj.text = $.jtwitter.utils.filterReplies( tweetObj.text );
			    
			
				var html = '';
				var altUser = '';
				altUser = (defaultOptions.user.username == tweetObj.user.screen_name ? 'alt' : '');
				
			 
				html += '<li class="jtwitter-tweet ' + altUser + '" id="jtwitter-tweet-' + tweetObj.id + '">';
				html += '<ul>';
				if (defaultOptions.showActions == true) {
					html += $.jtwitter.builders.buildActions( 'tweet', tweetObj);
				}
				html += '<li class="jtwitter-profile-image"><img rel="jtwitter-tip" name="#jtwitter-user-'+i+'" src="' + tweetObj.user.profile_image_url + '" alt="Photo of ' + tweetObj.user.name + '"/></li>';
				html += '<li class="jtwitter-screen-name" name="' + tweetObj.id + '">';
				html += '<a class="jtwitter-url" href="http://twitter.com/' + tweetObj.user.screen_name + '" title="' + tweetObj.user.screen_name + '" rel="bookmark" name="#jtwitter-meta-' + tweetObj.id + '">';
				
                if ( tweetObj.user['protected'] == true )
                {
                    html += '<span class="ui-icon ui-icon-locked"></span>';
                }
                html += tweetObj.user.screen_name + '';
				html += '</a></li>';
				html += '<li class="jtwitter-text">' + tweetObj.text + '</li>';
				html += '<li class="jtwitter-time">';
				html += '<span class="jtwitter-created-at">' + $.jtwitter.utils.prettifyDate(tweetObj.created_at) + ' </span>';
				html += '<span class="jtwitter-source">via ' + tweetObj.source + '</span>';
				html += '</li>';
				
				html += '<li id="jtwitter-meta-' + tweetObj.id + '" class="jtwitter-meta" style="display:none;">';
				html += '<span class="jtwitter-friends"><a title="Following ' + tweetObj.user.friends_count + ' members">' + tweetObj.user.friends_count + '</a> following</span> / ';
				html += '<span class="jtwitter-followers"><a title="' + tweetObj.user.followers_count + ' followers">' + tweetObj.user.followers_count + '</a> followers</span> / ';
				//html += '<span class="jtwitter-favorites"><a title="' + tweetObj.user.favourites_count + ' favorites">' + tweetObj.user.favourites_count + '</a> favorites</span> / ';
				html += '<span class="jtwitter-updates"><a rel="' + tweetObj.user.id + '" title="' + tweetObj.user.screen_name + ' Tweets" href="#">' + tweetObj.user.statuses_count + '</a> tweets / </span>';
				html += '<a href="http://twitter.com/'+tweetObj.user.screen_name+'" rel="bookmark" target="_blank" title="'+tweetObj.user.screen_name+' profile">View profile</a>';

				html += '</li>';
				html += '<li class="jtwitter-clear"></li>';
				html += '</ul>';
				html += $.jtwitter.builders.buildUser(i, tweetObj.user);
				html += '</li>';
				
				return html;
			},
			
			buildMessages: function(i, msgObj){
				var html = '';
				html += '<li class="jtwitter-tweet" id="jtwitter-message-' + msgObj.id + '"><ul>';
				if (defaultOptions.showActions == true) {
				//	html += $.jtwitter.builders.buildActions( 'message', msgObj);
				}
				html += '<li class="jtwitter-profile-image"><img src="' + msgObj.sender.profile_image_url + '" alt="Photo of ' + msgObj.sender.name + '"/></li>';
				html += '<li class="jtwitter-screen-name"><a class="jtwitter-url" href="http://twitter.com/' + msgObj.sender.screen_name + '" title="' + msgObj.sender.screen_name + '" rel="bookmark" target="_blank">' + msgObj.sender.screen_name + '</a></li>';
				html += '<li class="jtwitter-text">' + msgObj.text + '</li>';
				html += '<li class="jtwitter-time"><span class="jtwitter-created-at">' + $.jtwitter.utils.prettifyDate(msgObj.created_at) + ' </span></li>';
				html += '<li class="jtwitter-clear"></li>';
				html += '</ul></li>';
				
				return html;
			},
			
			buildImages: function(i, userObj){
				var html = '<li id="jtwitter-user-' + userObj.id + '" class="jtwitter-profile-image">';
				html += '<a class="jtwitter-url" href="http://twitter.com/' + userObj.screen_name + '" title="' + userObj.screen_name + '" rel="bookmark" target="_blank">';
				html += '<img src="' + userObj.profile_image_url + '" alt="Photo of ' + userObj.name + '"/></a></li>';
				
				return html;
			},
			
			buildTrends: function(i, trendObj){
				var html = '';
				html += '<li class="jtwitter-trend"><a href="' + trendObj.url + '">' + trendObj.name + '</a></li>';
				
				return html;
			},
			
			buildSearch: function(i, searchObj){
				var html = '';
				html += '<li class="jtwitter-search">' + searchObj.text + '</li>';
				
				return html;
			},
			
			buildActions: function( type, tweetObj){
				var html = '';
				html += '<li class="jtwitter-actions">';
				html += '<div>';
				if (tweetObj.user.screen_name == defaultOptions.user.username) {
					html += '<li class="ui-state-default ui-corner-all"><a href="#" title="' + tweetObj.user.screen_name + '" class="jtwitter-action-delete" rel="' + tweetObj.id + '"><span class="ui-icon ui-icon-trash">delete</span></a></li>';
				} else if ( type == 'tweet' ){
					html += '<li class="ui-state-default ui-corner-all"><a href="#" title="' + tweetObj.user.screen_name + '" class="jtwitter-action-reply" rel="' + tweetObj.id + '"><span class="ui-icon ui-icon-arrowreturnthick-1-w">reply</span></a></li>';
				} else if ( type == 'message' ){
				    //html += '<li class="ui-state-default ui-corner-all"><a href="#" title="' + tweetObj.sender.screen_name + '" class="jtwitter-action-message" rel="' + tweetObj.sender.id + '"><span class="ui-icon ui-icon-mail-closed">message</span></a></li>';
				}
								
				var favUnfav1 = (tweetObj.favorited == true) ? 'active' : 'default';
				var favUnfav2 = (tweetObj.favorited == true) ? 'unfavorite' : 'favorite';
				
				
				html += '<li class="ui-state-' + favUnfav1 + ' ui-corner-all"><a href="#" title="' + favUnfav2 + ' tweet" class="jtwitter-action-' + favUnfav2 + '" rel="' + tweetObj.id + '"><span class="ui-icon ui-icon-star">favorite</span></a></li>';
				//html += '<li><a href="#" class="jtwitter-action-block" rel="' + tweetObj.user.id + '">block</a></li>';
                html += '<br class="jtwitter-clear"/>';
				html += '</div>';
				html += '</li>';
				//html += '<li class="jtwitter-clear"></li>';
				
				return html;
			},
			
			buildUser: function(i, userObj){
				var html = '';
				html += '<div class="jtwitter-tooltip" id="jtwitter-user-' + i + '" title="'+userObj.screen_name+' Profile">';
				html += '<ul class="jtwitter-user-bio">';
				html += '<li class="jtwitter-screen-name"><a class="jtwitter-url" href="http://twitter.com/' + userObj.screen_name + '" title="' + userObj.screen_name + '" rel="bookmark">'+userObj.screen_name + '</a></li>';
				html += '<li class="jtwitter-profile-image"><img src="' + userObj.profile_image_url + '" alt="Photo of ' + userObj.name + '"/></li>';
				html += '<li>Name: <span class="jtwitter-user-name">' + userObj.name + '</span></li>';
				html += '<li>Location: <span class="jtwitter-user-location">' + userObj.location + '</span></li>';
				html += '<li>Web: <a class="jtwitter-user-url" href="' + userObj.url + '">' + userObj.url + '</a></li>';
				html += '<li>Bio: <span class="jtwitter-user-description"' + userObj.friends_count + '</span></li>';
				html += '<li class="jtwitter-meta">';
				html += '<span class="jtwitter-friends">' + userObj.friends_count + ' following</span> / ';
				html += '<span class="jtwitter-followers">' + userObj.followers_count + ' followers</span> / ';
				html += '<span class="jtwitter-favorites">' + userObj.favourites_count + ' favorites</span> / ';
			    html += '<span class="jtwitter-updates">' + userObj.statuses_count + ' tweets</span>';
				html += '</li>';
				html += '</ul>';
				html += '</div>';
				
				return html;
			},
			
			buildRateStatus: function(statusObj){
				var html = '';
				html += '<li>API Hits: ' + statusObj.remaining_hits + '</li>';
				html += '<li>Hourly Limit: ' + statusObj.hourly_limit + '</li>';
				html += '<li>Reset Time: ' + statusObj.reset_time + '</li>';
				return html;
			}
		},
		utils: {
		    refreshData: function(){
		        window.console.log('Refreshing All Data');
		    },
			prettifyDate: function(time){
				var values = time.split(" ");
				time = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
				
				var parsed_date = Date.parse(time);
				
				var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
				
				var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
				delta = delta + (relative_to.getTimezoneOffset() * 60);
				
				var out = '';
				
				if (delta < 60) {
					out = 'a minute ago';
				} else if (delta < 120) {
					out = 'couple of minutes ago';
				} else if (delta < (45 * 60)) {
					out = (parseInt(delta / 60)).toString() + ' minutes ago';
				} else if (delta < (90 * 60)) {
					out = 'an hour ago';
				} else if (delta < (24 * 60 * 60)) {
					out = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
				} else if (delta < (48 * 60 * 60)) {
					out = '1 day ago';
				} else {
					out = (parseInt(delta / 86400)).toString() + ' days ago';
				}
				
				return out;
			},

			filterUrl: function(text)
        	{
        		var regexp = /https?:\/\/(\w*:\w*@)?[-\w.]+(:\d+)?(\/([\w\/_.]*(\?\S+)?)?)?/gim;
        		var matches = text.match(regexp);

        		if (matches == null)
        		{
        			return text;
        		} else {

        			for ( i = 0; i < matches.length; i++ ) {
        				var replaced = '';
        				var link = '<a href="'+matches[i]+'" class="jtwitter-tweet-twitpic jtwitter-url" rel="bookmark" title="'+matches[i]+'">'+matches[i]+'</a>';
        				replaced = text.replace(matches[i], link);
        			}
        			return replaced;
        		}
        	},
        	
			filterReplies: function(text)
			{
			    var regexp = /\@+?\w*/gim;
        		var matches = text.match(regexp);

        		if (matches == null)
        		{
        			return text;
        		} else {

        			for ( i = 0; i < matches.length; i++ ) {
        				var replaced = '';

        				var user = String(matches[i]).replace('@', '');
        				var link = '<a href="http://twitter.com/' + user + '" class="jtwitter-mentioned-user jtwitter-url" rel="bookmark" title="'+user+'">@'+user+'</a>';
        				replaced = text.replace('@'+user, link);
        			}
        			return replaced;
        		}
			},
			
			checkUser: function(){
				if (defaultOptions.user.username === null && defaultOptions.user.password === null) {
					alert('You must login for that. Please try again.');
					return false;
				} else {
					return true;
				}
			},
			
			defaultActions: function(){
			  $('.jtwitter-url').live('click', function(){
			      var id = $(this).attr('name');
			     $(id).toggle('slow');
			     return false;
			  }); 
			  
			  if (defaultOptions.tweetarea)
			  {
			      $(defaultOptions.tweetarea).bind('keydown', function(event){
          			var msgMax = 140;
          			var msgCurrent = ( $(this).val().length + 0);
          			var msgRemaining = (msgMax - msgCurrent);

          			$(defaultOptions.tweetareaCount).html(msgRemaining);

          			//twitter_pod_button_update
          			if (msgRemaining < 0) {
          				$(defaultOptions.tweetarea).addClass('ui-state-error');
          			} else {
          				$(defaultOptions.tweetarea).removeClass('ui-state-error');
          			}
          		});
			  }
      			
			},//Ends defaultActions
			
			handleActions: function(){
			
				/***************************Favorite Actions**************************/
				//Add
				$('.jtwitter-action-favorite').live('click', function(){
					var link = this;
					var confirm = true;
					if (confirm == true) {
						$.jtwitter.createFavorite($(this).attr('rel'), function(result){
							$(link).parent().removeClass('ui-state-default').addClass('ui-state-active');
							$(link).removeClass('jtwitter-action-favorite').addClass('jtwitter-action-unfavorite');
						});
					} else {
						return false;
					}
					return false;
				});
				//Remove
				$('.jtwitter-action-unfavorite').live('click', function(){
					var link = $(this);
					var confirm = true;
					if (confirm == true) {
						$.jtwitter.deleteFavorite($(this).attr('rel'), function(result){
							$(link).parent().removeClass('ui-state-active').addClass('ui-state-default');
							$(link).removeClass('jtwitter-action-unfavorite').addClass('jtwitter-action-favorite');
							return false;
						});
					} else {
						return false;
					}
				});
				
				/***************************Message Actions**************************/
				$('.jtwitter-action-message').bind('click', function(event){
					alert('Message to user id: ' + $(this).attr('rel'));
				});
				
				/***************************Block Actions**************************/
				$('.jtwitter-action-block').live('click', function(){
					alert('Block user id: ' + $(this).attr('rel'));
				});
				
				/***************************Reply Actions**************************/
				$('.jtwitter-action-reply').live('click', function(){
					$(defaultOptions.tweetarea).val('@' + $(this).attr('title')).focus();
					//alert( 'Reply to tweet id: ' + $(this).attr('rel'));
				});
				
				/***************************Follow Actions**************************/
				$('.jtwitter-action-follow').live('click', function(){
					alert('Follow user id: ' + $(this).attr('rel'));
				});
				/***************************Delete Actions**************************/
				$('.jtwitter-action-delete').live('click', function(){
					var confirmCheck = confirm('Are you sure?');
					var id = $(this).attr('rel');
					if (confirmCheck == true) {
						$.jtwitter.deleteTweet($(this).attr('rel'), function(result){
							$('#jtweet_' + id).remove('slow');
						});
					}
					
				});
				
				
				
			}
		}
	
	};//ends jTwitterObject

	//If auto load data is true
	if (defaultOptions.autoFetch) {
		if (defaultOptions.defaultTimeline == 'public') {
			$.jtwitter.getPublicTimeline();
		} else if (defaultOptions.defaultTimeline == 'user') {
			$.jtwitter.getUserTimeline();
		} else if (defaultOptions.defaultTimeline == 'friends') {
			$.jtwitter.getFriendsTimeline();
		}
	}
	
	if (defaultOptions.showActions) {
		$.jtwitter.utils.handleActions();
	}
	
	$.jtwitter.utils.defaultActions();
	
    
    
	return thisWrap;
};
})(jQuery);
